Shader "UI/TextOutlineHighWidth"
{
    Properties
    {
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
        _Color ("Text Color", Color) = (1,1,1,1)
        _OutlineColor ("Outline Color", Color) = (0,0,0,1)
        _OutlineWidth ("Outline Width", Range(0, 10)) = 2
        _Softness ("Outline Softness", Range(0, 1)) = 0.2
        _MaxSamplingRadius ("Max Sampling Radius", Range(1, 5)) = 3
    }

    SubShader
    {
        Tags
        {
            "Queue"="Transparent"
            "IgnoreProjector"="True"
            "RenderType"="Transparent"
            "PreviewType"="Plane"
            "CanUseSpriteAtlas"="True"
        }

        Cull Off
        Lighting Off
        ZWrite Off
        ZTest [unity_GUIZTestMode]
        Blend SrcAlpha OneMinusSrcAlpha

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile __ HIGH_WIDTH_MODE
            
            #include "UnityCG.cginc"
            #include "UnityUI.cginc"

            struct appdata_t
            {
                float4 vertex   : POSITION;
                float4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex   : SV_POSITION;
                fixed4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
                float4 worldPosition : TEXCOORD1;
            };

            sampler2D _MainTex;
            fixed4 _Color;
            fixed4 _OutlineColor;
            float _OutlineWidth;
            float _Softness;
            float _MaxSamplingRadius;
            float4 _ClipRect;
            float4 _MainTex_ST;
            float4 _MainTex_TexelSize;

            v2f vert(appdata_t v)
            {
                v2f OUT;
                OUT.worldPosition = v.vertex;
                OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
                OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
                OUT.color = v.color * _Color;
                return OUT;
            }

            // 计算采样权重函数
            float calcOutlineWeight(float2 offset, float maxRadius)
            {
                float dist = length(offset * maxRadius);
                return smoothstep(0.0, 1.0, 1.0 - saturate(dist / maxRadius));
            }

            fixed4 frag(v2f IN) : SV_Target
            {
                // 计算基础偏移量
                float2 baseOffset = _MainTex_TexelSize.xy;
                
                // 中心点采样
                half4 center = tex2D(_MainTex, IN.texcoord);
                
                // 计算实际需要的采样半径
                float samplingRadius = min(_OutlineWidth, _MaxSamplingRadius);
                
                // 早期Alpha测试 - 跳过完全透明区域
                if (center.a < 0.01) discard;
                
                // 高质量大宽度描边模式
                #ifdef HIGH_WIDTH_MODE
                    half maxAlpha = center.a;
                    float totalWeight = 0.0;
                    
                    // 动态采样点数量（基于半径）
                    int steps = (int)clamp(samplingRadius * 2.0, 8, 16);
                    float angleStep = 6.28318530718 / steps;
                    
                    // 圆形采样
                    for (int i = 0; i < steps; i++)
                    {
                        float angle = angleStep * i;
                        float2 dir = float2(cos(angle), sin(angle));
                        float2 sampleUV = IN.texcoord + dir * baseOffset * samplingRadius;
                        
                        // 采样并计算权重
                        half sampleAlpha = tex2D(_MainTex, sampleUV).a;
                        float weight = calcOutlineWeight(dir, samplingRadius);
                        
                        maxAlpha = max(maxAlpha, sampleAlpha * weight);
                        totalWeight += weight;
                    }
                    
                    // 归一化
                    maxAlpha = saturate(maxAlpha / max(1, totalWeight / steps));
                    
                // 标准模式
                #else
                    // 8方向采样
                    float2 offsets[8] = {
                        float2(1, 0), float2(0, 1), float2(-1, 0), float2(0, -1),
                        float2(0.707, 0.707), float2(-0.707, 0.707),
                        float2(-0.707, -0.707), float2(0.707, -0.707)
                    };
                    
                    half maxAlpha = center.a;
                    
                    for (int i = 0; i < 8; i++)
                    {
                        float2 sampleUV = IN.texcoord + offsets[i] * baseOffset * samplingRadius;
                        half sampleAlpha = tex2D(_MainTex, sampleUV).a;
                        maxAlpha = max(maxAlpha, sampleAlpha);
                    }
                #endif
                
                // 计算描边强度（边缘柔化处理）
                half outlineIntensity = smoothstep(0, _Softness, maxAlpha - center.a);
                
                // 组合颜色
                fixed4 col = lerp(_OutlineColor, IN.color, center.a);
                col.a = max(center.a, outlineIntensity * _OutlineColor.a);
                
                // UI裁剪
                col.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
                
                return col;
            }
            ENDCG
        }
    }
}